using System;
using System.Collections;
using System.Collections.Generic;
using LdtJudge.DataEngine.Model.DataModel.SysCommon;

namespace LdtJudge.DataEngine.DataBaseStores.Cached
{
    /**
     * MSYS_Express_Source 表的缓存类，缓存了业务中用到的所有数据，这个
     * 数据在运行中很多地方都会用到，所以做了这个缓存来加速这些业务代码的
     * 执行效率。
     * 
     * @author li zhen
     */
    public class MsysExpressSourceCached
    {
        public static readonly HashSet<string> EsIdSt = new HashSet<string>();
        public static readonly Hashtable EsIdHt = new Hashtable();
        public static readonly Hashtable CcIdHt = new Hashtable();
        public static readonly Hashtable SourceParagraphIdHt = new Hashtable();
        public static readonly Hashtable SourceTextTypeHt = new Hashtable();
        public static readonly Hashtable AmCodeHt = new Hashtable();
        public static readonly Hashtable EsPurposeHt = new Hashtable();
        public static readonly Hashtable SourceIdHt = new Hashtable();

        private static readonly HashSet<string> EmptySet = new HashSet<string>();
        private static readonly List<MSYS_Express_Source> EmptyList = new List<MSYS_Express_Source>();

        static List<MSYS_Express_Source> _source;

        public static void Initialization(List<MSYS_Express_Source> source)
        {
            MsysExpressSourceCached._source = source;

            for (int i = 0; i < _source.Count; i++)
            {
                var es = _source[i];
                var esId = i.ToString();

                EsIDhtInitialize(es, esId);

                CcIDhtInitialize(es, esId);

                SourceParagraphIDhtInitialize(es, esId);

                SourceTextTypeHtInitialize(es, esId);

                SourceIdHtInitialize(es, esId);

                AmCodeHtAmCodeHtInitialize(es, esId);

                EsPurposeHtInitialize(es, esId);
            }
        }

        private static void EsIDhtInitialize(MSYS_Express_Source es, string esId)
        {
            if (esId != null)
            {
                EsIdSt.Add(esId);

                if (!EsIdHt.ContainsKey(esId))
                {
                    EsIdHt[esId] = es;
                }
            }
        }

        private static void CcIDhtInitialize(MSYS_Express_Source es, string esId)
        {
            var ccId = es.CC_ID;
            if (ccId != null)
            {
                HashSet<string> inset;

                if (CcIdHt.ContainsKey(ccId))
                {
                    inset = CcIdHt[ccId] as HashSet<string>;
                }
                else
                {
                    inset = new HashSet<string>();
                    CcIdHt[ccId] = inset;
                }

                inset?.Add(esId);
            }
        }

        private static void SourceTextTypeHtInitialize(MSYS_Express_Source es, string esId)
        {
            var key = es.Source_texttype;
            if (key != null)
            {
                HashSet<string> inset;

                if (SourceTextTypeHt.ContainsKey(key))
                {
                    inset = SourceTextTypeHt[key] as HashSet<string>;
                }
                else
                {
                    inset = new HashSet<string>();
                    SourceTextTypeHt[key] = inset;
                }

                inset?.Add(esId);
            }
        }

        private static void SourceIdHtInitialize(MSYS_Express_Source es, string esId)
        {
            var key0 = es.Source_ID;
            if (key0 != null)
            {
                var keys = key0.Split(',');

                foreach (var key in keys)
                {
                    HashSet<string> inset;

                    if (SourceIdHt.ContainsKey(key))
                    {
                        inset = SourceIdHt[key] as HashSet<string>;
                    }
                    else
                    {
                        inset = new HashSet<string>();
                        SourceIdHt[key] = inset;
                    }

                    inset?.Add(esId);
                }
            }
        }

        private static void SourceParagraphIDhtInitialize(MSYS_Express_Source es, string esId)
        {
            if (es.Source_ParagraphID != null)
            {
                var spId = es.Source_ParagraphID.ToLower();
                HashSet<string> inset;

                if (SourceParagraphIdHt.ContainsKey(spId))
                {
                    inset = SourceParagraphIdHt[spId] as HashSet<string>;
                }
                else
                {
                    inset = new HashSet<string>();
                    SourceParagraphIdHt[spId] = inset;
                }

                inset?.Add(esId);
            }
        }

        private static void AmCodeHtAmCodeHtInitialize(MSYS_Express_Source es, string esId)
        {
            var key = es.Am_code;
            if (key != null)
            {
                HashSet<string> inset;

                if (AmCodeHt.ContainsKey(key))
                {
                    inset = AmCodeHt[key] as HashSet<string>;
                }
                else
                {
                    inset = new HashSet<string>();
                    AmCodeHt[key] = inset;
                }

                inset?.Add(esId);
            }
        }

        private static void EsPurposeHtInitialize(MSYS_Express_Source es, string esId)
        {
            var key = es.Es_purpose;
            if (key != null)
            {
                HashSet<string> inset;

                if (EsPurposeHt.ContainsKey(key))
                {
                    inset = EsPurposeHt[key] as HashSet<string>;
                }
                else
                {
                    inset = new HashSet<string>();
                    EsPurposeHt[key] = inset;
                }

                inset?.Add(esId);
            }
        }
        public static HashSet<string> Copy_Hash(HashSet<string> one) 
        {


            //HashSet<string> result = new HashSet<string>();

            //foreach (var key in one)
            //{
            //  result.Add(key);
            //}

            return one;
        }
        /**
         * hashset 取交集
         */
        public static HashSet<string> HashSet_String_Intersection(Object one, Object two)
        {
            if (one == null || two == null)
            {
                return EmptySet;
            }

            var oneHt = one as HashSet<string>;
            var twoHt = two as HashSet<string>;

            var driver = oneHt.Count < twoHt.Count ? oneHt : twoHt;
            var driven = oneHt.Count < twoHt.Count ? twoHt : oneHt;

            HashSet<string> result = new HashSet<string>();

            foreach (var key in driver)
            {
                if (driven.Contains(key))
                {
                    result.Add(key);
                }
            }

            return result;
        }

        /**
         * hashset 转换成需要用的 IReadOnlyList<MSYS_Express_Source>
         */
        public static List<MSYS_Express_Source> Restore(HashSet<string> keys)
        {
            if (keys == null)
            {
                return EmptyList;
            }

            List<MSYS_Express_Source> result = new List<MSYS_Express_Source>(keys.Count);

            foreach (var key in keys)
            {
                if (EsIdHt.Contains(key))
                {
                    result.Add(EsIdHt[key] as MSYS_Express_Source);
                }
            }

            return result;
        }
    }
}